package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.comment.fegin.ApUserFegin;
import com.heima.comment.service.CommentService;
import com.heima.comment.service.HotCommentService;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.constants.HotArticleConstants;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.vo.ApCommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.mess.UpdateArticleMess;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.threadlocal.AppThreadLocalUtils;
import com.mongodb.client.result.DeleteResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author feng js
 */
@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    ApUserFegin apUserFegin;
    @Autowired
    GreenTextScan greenTextScan;
    @Autowired
    private KafkaTemplate kafkaTemplate;

    /**
     * 保存评论
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (dto.getContent() != null && dto.getContent().length() > 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论字数过多");
        }
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        try {
            Map map = greenTextScan.greeTextScan(dto.getContent());
            String suggestion = (String) map.get("suggestion");
            if (suggestion.equals("block")||suggestion.equals("review")) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论审核不通过");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论审核不通过");
        }
        ApUser apUserFeginUser = apUserFegin.findUserById(user.getId());
        if (apUserFeginUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST);
        }
        ApComment apComment = new ApComment();
        apComment.setAuthorId(apUserFeginUser.getId());
        apComment.setAuthorName(apUserFeginUser.getName());
        apComment.setContent(dto.getContent());
        apComment.setEntryId(dto.getArticleId());
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        apComment.setImage(apUserFeginUser.getImage());
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setType((short) 0);
        apComment.setFlag((short) 0);
        //发送消息
        UpdateArticleMess mess = new UpdateArticleMess();
        mess.setAdd(1);
        mess.setType(UpdateArticleMess.UpdateArticleType.COMMENT);
        mess.setArticleId(dto.getArticleId());
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC, UUID.randomUUID().toString(), JSON.toJSONString(mess));

        mongoTemplate.insert(apComment);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Autowired
    private HotCommentService hotCommentService;

    @Override
    public ResponseResult like(CommentLikeDto dto) {

        if (dto==null||dto.getCommentId() == null || dto.getOperation() >1||dto.getOperation()<0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //判断是否登录，不登陆不能点赞
        ApUser apUser = AppThreadLocalUtils.getUser();
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_EXPIRE);
        }
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if (apComment != null && dto.getOperation() == 0) {
            apComment.setLikes(apComment.getLikes() + 1);
            apComment.setUpdatedTime(new Date());
            mongoTemplate.save(apComment);
            //计算当前评论是否是热点评论
            if (apComment.getLikes() >= 5 && apComment.getFlag() == 0) {
                hotCommentService.findHotComment(apComment.getEntryId(),apComment);
            }
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(apComment.getAuthorId());
            apCommentLike.setCommentId(apComment.getId());
            mongoTemplate.save(apCommentLike);
        } else if (apComment != null && dto.getOperation() == 1) {
            apComment.setLikes(apComment.getLikes()<=0?0:apComment.getLikes()-1);
            apComment.setUpdatedTime(new Date());
            mongoTemplate.save(apComment);
            mongoTemplate.remove(Query.query(Criteria.where("authorId").is(apUser.getId()).and("commentId").is(apComment.getId())),ApCommentLike.class);

        }
        Map<String, Object> map = new HashMap<>();
        map.put("likes", apComment.getLikes());
        return ResponseResult.okResult(map);
    }

    @Override
    public ResponseResult findByArticleId(CommentDto dto) {

        if (dto.getArticleId() == null || dto.getMinDate() == null || dto.getIndex() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
      List<ApComment> apComments = null;
        int size = 10;
        //当前是首页
        if (dto.getIndex() == 1) {
            Query hostqQuery = Query.query(Criteria.where("entryId").is(dto.getArticleId()).and("flag").is(1)).with(Sort.by(Sort.Direction.DESC, "likes"));
             apComments = mongoTemplate.find(hostqQuery, ApComment.class);
            if (apComments.size() > 0) {
                size = size - apComments.size();
                Query namlQuery = Query.query(Criteria.where("entryId").is(dto.getArticleId()).and("flag").is(0).and("createdTime").lt(dto.getMinDate()))
                        .limit(size).with(Sort.by(Sort.Direction.DESC, "createdTime"));
                List<ApComment> namalComment = mongoTemplate.find(namlQuery, ApComment.class);
                apComments.addAll(namalComment);

            } else {
                Query namlQuery2 = Query.query(Criteria.where("entryId").is(dto.getArticleId()).and("flag").is(0).and("createdTime").lt(dto.getMinDate()))
                        .limit(size).with(Sort.by(Sort.Direction.DESC, "createdTime"));
                apComments = mongoTemplate.find(namlQuery2, ApComment.class);
            }
        } else {
            Query namlQuery2 = Query.query(Criteria.where("entryId").is(dto.getArticleId()).and("flag").is(0).and("createdTime").lt(dto.getMinDate()))
                    .limit(size).with(Sort.by(Sort.Direction.DESC, "createdTime"));
            apComments = mongoTemplate.find(namlQuery2, ApComment.class);
        }
        //判断是否登录
        ApUser apUser = AppThreadLocalUtils.getUser();
        if (apUser == null) {
            //没有登录时，直接展示评论
            return ResponseResult.okResult(apComments);
        }
        //登录时展示当前用户点赞的评论要高亮
        //查询当前用户点赞的评论
        List<String> idList = apComments.stream().map(ApComment::getId).collect(Collectors.toList());
        Query query1 = Query.query(Criteria.where("commentId").in(idList).and("authorId").is(apUser.getId()));
        List<ApCommentLike> apCommentLikes = mongoTemplate.find(query1, ApCommentLike.class);
        List<ApCommentVo> apCommentVos = new ArrayList<>();

        if (apCommentLikes.size() > 0) {
            apComments.stream().forEach(apComment -> {
                ApCommentVo apCommentVo = new ApCommentVo();
                BeanUtils.copyProperties(apComment, apCommentVo);
                for (ApCommentLike apCommentLike : apCommentLikes) {
                    if (apComment.getId().equals(apCommentLike.getCommentId())) {
                        apCommentVo.setOperation((short) 0);
                        break;
                    }

                }
                apCommentVos.add(apCommentVo);
            });
            return ResponseResult.okResult(apCommentVos);
        } else {
            return ResponseResult.okResult(apComments);
        }

    }
}
